package sen.queryUtils;
import java.io.StringReader;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;


public class MyUtils {

	public static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	public static final SimpleDateFormat SDF_NO_SECOND = new SimpleDateFormat("yyyy-MM-dd HH:mm");
	public static final SimpleDateFormat SDF_NO_TIME = new SimpleDateFormat("yyyy-MM-dd");
	/**
	 * 将给定list<id>拼成 or sql 串
	 * @param ids : 源数据，只能是集合或String[]
	 * @param id : 某列名 = x or 某列名 = y
	 * @param isStr
	 * @return (x='v1' or x='v2')
	 * @throws Exception
	 */
	public static String getOrStr(Object o, String id, boolean isStr) throws Exception {
		if(o == null) {
			return "";
		}
		StringBuilder sql = new StringBuilder("(");
		if(o instanceof Collection<?>) {
			Collection<?> ids = (Collection<?>)o;
			if(ids.isEmpty()) {
				throw new Exception("源数据为空");
			}
			
			for(Iterator itr = ids.iterator(); itr.hasNext();) {
				if(isStr) { //说明是字符型的
					sql.append(" " + id + "='" + itr.next() + "' or ");
				} else {
					sql.append(" " + id + "=" + itr.next() + " or ");
				}
			}
		} else if(o.getClass().isArray()) {
			String[] sA = (String[])o;
			if(null==sA || sA.length<1) {
				throw new Exception("源数据为空");
			}
			for (int i = 0; i < sA.length; i++) {
				sql.append(" " + id + "='" + sA[i] + "' or ");
			}
		}
		
		sql.delete(sql.lastIndexOf("or"), sql.length()-1);
		sql.append(")");
		return sql.toString();
	}
	
	/**
	 * 判断一批对象是否为null 或 ""
	 * @param o
	 * @return
	 */
	public static boolean isNull(Object...o) {
		for (int i = 0; i < o.length; i++) {
			if(null==o[i] || "".equals(o[i].toString())){
				return true;
			}
		}
		return false;
	}
	/**
	 * 判断一批对象是否equals
	 * 如果有null值直接返回false
	 * @param o
	 * @return
	 */
	public static boolean eq(Object...o) {
		for(int i = 0; i < o.length-1; i++) {
			if(null==o[i] || !o[i].toString().equals(o[i+1].toString())) {
				return false;
			}
		}
		return true;
	}
	
	/**
	 * 8/31/11 9:49	形式的时间转成 2011-08-31 09:49:00
	 * @param src
	 * @return
	 * @throws ParseException 
	 */
	public static String parseTime(String src) throws ParseException {
		SimpleDateFormat inSdf = new SimpleDateFormat("M/dd/yy hh:mm");
		SimpleDateFormat outSdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
		Date dateS = inSdf.parse(src);
		return outSdf.format(dateS);
	}
	
	/*********************************
	 * ===========一堆字符串转数字======
	 * ===========方法后缀有2的表示转不成则返回null 
	 */
	public static Byte stringToByte2(String s) {
		if(null == s) return null; 
		try {
			return Byte.parseByte(s);
		} catch (Exception e) {
		}
		return null;
	}
	public static Byte stringToByte(String s) {
		try {
			return Byte.parseByte(s);
		} catch (Exception e) {
		}
		return 0;
	}
	public static float stringToFloat(String s) {
		try {
			return Float.parseFloat(s);
		} catch (Exception e) {
		}
		return 0;
	}
	public static Float stringToFloat2(String s) {
		try {
			return Float.parseFloat(s);
		} catch (Exception e) {
		}
		return null;
	}
	public static Integer stringToInteger(String s) {
		try {
			return Integer.parseInt(s);
		} catch (Exception e) {
		}
		return 0;
	}
	public static Integer stringToInteger2(String s) {
		if(null == s) return null;
		try {
			return Integer.parseInt(s);
		} catch (Exception e) {
		}
		return null;
	}
	public static Short stringToShortNum(String s) {
		try {
			return Short.parseShort(s);
		} catch (Exception e) {
		}
		return 0;
	}
	public static Short stringToShortObj(String s) {
		if(null == s) return null;
		try {
			return Short.parseShort(s);
		} catch (Exception e) {
		}
		return null;
	}
	/**
	 * @param s
	 * @return 转不了则返回0
	 */
	public static Long stringToLong(String s) {
		try {
			return Long.parseLong(s);
		} catch (Exception e) {
		}
		return 0L;
	}
	/**
	 * @param s
	 * @return 转不了则返回null
	 */
	public static Long stringToLong2(String s) {
		if(null == s) return null; 
		try {
			return Long.parseLong(s);
		} catch (Exception e) {
		}
		return null;
	}
	//*********************************//
	/**
	 * 正则匹配
	 * 
	 * @param s
	 * @param pattern
	 * @return
	 */
	public static String[] match(String s, String pattern) {
		Matcher m = Pattern.compile(pattern).matcher(s);

		while (m.find()) {
			int n = m.groupCount();
			String[] ss = new String[n + 1];
			for (int i = 0; i <= n; i++) {
				ss[i] = m.group(i);
			}
			return ss;
		}
		return null;
	}
	
	/**
	 * 正则匹配
	 * 
	 * @param s
	 * @param pattern
	 * @return
	 */
	public static List<String[]> matchAll(String s, String pattern) {
		Matcher m = Pattern.compile(pattern).matcher(s);
		List<String[]> result = new ArrayList<String[]>();

		while (m.find()) {
			int n = m.groupCount();
			String[] ss = new String[n + 1];
			for (int i = 0; i <= n; i++) {
				ss[i] = m.group(i);
			}
			result.add(ss);
		}
		return result;
	}
	/**
	 * 字符串首字母大写
	 * @param s
	 * @return
	 */
	public static String upperFirst(String s) {
		String f = s.substring(0,1);
		String o = s.substring(1, s.length());
		return f.toUpperCase()+o;
	}
	
	public static String objToJsonStr(Object o) {
		return buildGson().toJson(o, o.getClass());
	}
	public static Gson buildGson() {
		GsonBuilder builder = new GsonBuilder();
    	builder.excludeFieldsWithoutExposeAnnotation();
        Gson gson = builder.create();
        return gson;
	}
	/**
	 * 删除字符串最后一个字符串
	 * @param src 表示要处理的源字符串
	 * @param lastSrc 表示要删除的最后一个字符串，默认为,
	 * @return
	 */
	public static void delLast(StringBuilder src, String lastSrc, String pre, String end) {
		if(isNull(src.toString())) {
			return;
		}
		src.delete(src.lastIndexOf(lastSrc), src.length());
		if(!isNull(pre)){
			src.insert(0, pre);
		}
		if(!isNull(end)){
			src.append(end);
		}
	}
	public static void delLast(StringBuilder src, String lastSrc) {
		delLast(src,lastSrc,"","");
	}
	public static void delLast(StringBuilder src) {
		delLast(src,",","","");
	}
	
	public static String autoCreatePW(int pwLength){
		StringBuilder pw = new StringBuilder();
		String pwSrc = "1234567890";
		char[] pws = pwSrc.toCharArray();
		Random rd = new Random();
		int len = pws.length-1;
		for (int i = 0; i < pwLength; i++) {
			int in = rd.nextInt(len);
			pw.append(pws[in]);
		}
		return pw.toString();
	}
	
	public static String getMD5(String x) {
	  String s = null;
	  char hexDigits[] = {       // 用来将字节转换成 16 进制表示的字符
	     '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd',  'e', 'f'}; 
	   try
	   {
	    java.security.MessageDigest md = java.security.MessageDigest.getInstance( "MD5" );
	    md.update( x.getBytes() );
	    byte tmp[] = md.digest();          // MD5 的计算结果是一个 128 位的长整数，
	                                                // 用字节表示就是 16 个字节
	    char str[] = new char[16 * 2];   // 每个字节用 16 进制表示的话，使用两个字符，
	                                                 // 所以表示成 16 进制需要 32 个字符
	    int k = 0;                                // 表示转换结果中对应的字符位置
	    for (int i = 0; i < 16; i++) {          // 从第一个字节开始，对 MD5 的每一个字节
	                                                 // 转换成 16 进制字符的转换
	     byte byte0 = tmp[i];                 // 取第 i 个字节
	     str[k++] = hexDigits[byte0 >>> 4 & 0xf];  // 取字节中高 4 位的数字转换, 
	                                                             // >>> 为逻辑右移，将符号位一起右移
	     str[k++] = hexDigits[byte0 & 0xf];            // 取字节中低 4 位的数字转换
	    } 
	    s = new String(str);                                 // 换后的结果转换为字符串

	   }catch( Exception e )
	   {
	    e.printStackTrace();
	   }
	   return s;
	 }
	
	public static String getTimeText(Date time, String pattern){
		try {
			SimpleDateFormat sdf = new SimpleDateFormat(pattern);
			return sdf.format(time);
		} catch (Exception e) {
			return "";
		}
	}
	
	public static String getDateText(Date time){
		try {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			return sdf.format(time);
		} catch (Exception e) {
			return "";
		}
	}
	public static String getTimeText(Date time){
		try {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			return sdf.format(time);
		} catch (Exception e) {
			return "";
		}
	}
	
	public static String getTimeNoSText(Date time){
		try {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
			return sdf.format(time);
		} catch (Exception e) {
			return "";
		}
	}
	

	public static String get(String value) {
		return value==null?"":value;
	}
	public static String trim(String value) {
		return get(value).trim();
	}
	
	/**
	 * 将字符串通过dom4j转成xml元素
	 * @param s
	 * @return
	 */
	public static Element string2xml(String s) throws DocumentException{
        SAXReader builder = new SAXReader();
        Document doc = null;
        Element element=null;
        try {
            doc = builder.read(new StringReader(s));
        } catch (DocumentException e) {
            throw e;
        }
        if (doc!=null) {
            element=doc.getRootElement();
        }
        return element;
    }
	/**
	 * xml元素转成json字符串
	 * @param e
	 * @return
	 */
	public static String xml2json(Element e) {
		List l = e.elements();
		String json = "";
		if(l==null || l.isEmpty()){
			json = "{'"+e.getName()+"':'"+e.getStringValue()+"'}";
		} else {
			json = "{'"+e.getName()+"':{";
			StringBuilder s = xml2jsonDG(e);
			json = json + s + "}}";
		}
		return json;
	}
	/**
	 * 供xml2json访问的递归xml元素的方法
	 * @param e
	 * @return
	 */
	private static StringBuilder xml2jsonDG(Element e) {
		StringBuilder item = new StringBuilder();
		
		List l = e.elements();
		
		for (Iterator iterator = l.iterator(); iterator.hasNext();) {
			Element el = (Element) iterator.next();
			
			List es = el.elements();
			if(es==null || es.isEmpty()){
				item.append("'"+el.getName()+"':'"+el.getStringValue()+"',");
			} else {
				item.append("'"+ el.getName() +"':{");
				StringBuilder sb= xml2jsonDG(el);
				item.append(sb)
					.append("},");
			}
		}
		MyUtils.delLast(item,",","","");
		return item;
	}
	
	/**
	 * 将这种yyyy-MM-dd hh:mm:ss形式的字符串解析成Date对象
	 * @param s
	 * @return
	 */
	public static Date string2Date(String s) {
		Date dateS = null;
		try {
			dateS = SDF.parse(s);
		} catch (Exception e) {
		}
		return dateS;
	}
	/**
	 * 将这种yyyy-MM-dd形式的字符串解析成Date对象
	 * @param s
	 * @return
	 */
	public static Date string2DateNoTime(String s) {
		Date dateS = null;
		try {
			dateS = SDF_NO_TIME.parse(s);
		} catch (Exception e) {
		}
		return dateS;
	}
	/**
	 * 将这种yyyy-MM-dd HH:mm形式的字符串解析成Date对象
	 * @param s
	 * @return
	 */
	public static Date string2DateNoSecond(String s) {
		Date dateS = null;
		try {
			dateS = SDF_NO_SECOND.parse(s);
		} catch (Exception e) {
		}
		return dateS;
	}
	/**
	 * 将指定形式的字符串解析成Date对象
	 * @param s
	 * @param format 时间形式，如：yyyy-MM-dd hh:mm:ss
	 * @return
	 */
	public static Date string2Date(String s, String format) {
		SimpleDateFormat inSdf = new SimpleDateFormat(format);
		Date dateS = null;
		try {
			dateS = inSdf.parse(s);
		} catch (Exception e) {
		}
		return dateS;
	}
	
	/**
	 * 四舍五入，保留一位小数
	 * @param f
	 * @return
	 */
	public static float round(Object f){
		float x = stringToFloat(f+"");
		return (float)Math.round(x*10)/10;
	}
	/**
	 * 四舍五入，保留两位小数
	 * @param f
	 * @return
	 */
	public static float round2(Object f){
		float x = stringToFloat(f+"");
		return (float)Math.round(x*100)/100;
	}
	/**
	 * 四舍五入，保留三位小数
	 * @param f
	 * @return
	 */
	public static float round3(Object f){
		float x = stringToFloat(f+"");
		return (float)Math.round(x*1000)/1000;
	}

	public static int getDays(Date d1, Date d2){
		int days = 0;
		days = (int) ((d2.getTime()-d1.getTime())/1000/60/60/24);
		return days;
	}

	/**
	 * 将日期对象转成年月日的字符串数组 
	 * @return
	 */
	public static String[] getStringArrWithDate(Date d) {
		if(d==null){
			return null;
		}
		String ds = getDateText(d);
		return ds.split("-");
	}
	
	public static int getCurWeek(){
		Calendar c = Calendar.getInstance();
		c.setFirstDayOfWeek(GregorianCalendar.SUNDAY); 
        c.setMinimalDaysInFirstWeek(3);
		return c.get(Calendar.WEEK_OF_YEAR);
	}
}